Exercício 37#
Usar a STFT (quando possível) para analisar os sons de alguns sinais reais mencionados na Seção 5.3: a) fala; b) voz de cetáceo; c) som de hélice; d) resposta a irradiação por pulso de sonar; e) som de limpador de para-brisa; f) som de batida de porta; g) operação de máquina em funcionamento / em falha; h) operação de broca nova / gasta i) som de trompete; j) som de coração.
Resolução:#
O trabalho será realizado em python, em um notebook jupyter disponível a seguir, que pode ser acessado interativamente em https://www.smt.ufrj.br/~pedro.lopes/ex37/main.html. A STFT será realizada pela implementação da biblioteca librosa, junto com as funções para plotar os espectrogramas. Para facilitar a visualização, após a geração das STFT’s para cada sinal, mostraremos os respectivos espectrogramas de potência em escala logarítimica (dB).
Começamos por importar as bibliotecas necessárias:
import warnings
warnings.filterwarnings('ignore')
from librosa import stft
import librosa.display
import soundfile as sf
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import Audio
plt.rcParams["figure.figsize"] = (14,8)
plt.plot()
plt.close()
plt.show()
Agora definimos as funções para ler os arquivos de áudio e fazer o plot dos espectrogramas. As STFT’s operam com tamanho de janela 2048 e salto de 512 amostras. Os outros parâmetros (formato da janela, padding, etc) são os padrões da biblioteca.
def get_spectrogram_data(signal,samplerate,n_fft=2048, hop_length=512,start=0,end=10):
X = stft(signal[int(start*samplerate):int(end*samplerate)],n_fft=n_fft, hop_length=hop_length,win_length=n_fft)
X_db = librosa.amplitude_to_db(np.abs(X), ref=np.max)
return X_db
def play_audio(signal,samplerate,start=0,end=10):
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
def plot_spectrogram(signal, samplerate,n_fft=2048, hop_length=512,start=0,end=10,y_axis='linear'):
X_db = get_spectrogram_data(signal,samplerate,n_fft=n_fft, hop_length=hop_length,start=start,end=end)
fig, ax = plt.subplots()
img = librosa.display.specshow(X_db, sr=samplerate, x_axis='time', y_axis=y_axis, ax=ax)
ax.set_title('Espectrograma de potência, escala log (dB)')
fig.colorbar(img, ax=ax, format="%+2.0f dB")
ax.set_xlabel("Tempo (s)")
ax.set_ylabel("Frequência (Hz)")
plt.show()
a) Começando pelo sinal de fala, temos:
signal,samplerate = sf.read('sinais/fala.wav')
start = 0.4
end= 4.25
plot_spectrogram(signal,samplerate,start=start,end=end);
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
b) Para os cetáceos, os sinais foram obtidos na página http://www-9.unipv.it/cibra/edu_medsounds_uk.html. Lá, podemos obter quatro classes de sons produzidos por estes tipos de animais:
Os sons de baixa frequência (por volta de 20 Hz);
Os cliques que as baleias cachalotes emitem com um ritmo de 1-4 por segundo enquanto mergulham;
Os assobios de alta frequência modulados (variando em frequência para mais de 20 kHz);
e os cliques de ecolocalização emitidos pelos golfinhos pequenos;
Para cada um deles, trazemos um exemplo.
Começando pelos sons de baixa frequência, mostramos estes em escala logarítimica de frequência (para melhor visualização) e acelerados em 8x (para possibilitar a audição):
signal,samplerate = sf.read('sinais/low_freq.wav')
start = 0.4
end= 4.25
plot_spectrogram(signal,samplerate,start=start,end=end,y_axis='log', hop_length=1024, n_fft=2048)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
Agora os cliques das cachalotes:
signal,samplerate = sf.read('sinais/cachalotes_cliques.mp3')
signal = signal[:,0]
start = 3
end= 7
plot_spectrogram(signal,samplerate,start=start,end=end,hop_length=512,n_fft=1024)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
Assobios agudos:
signal,samplerate = sf.read('sinais/assobios.wav')
start = 0.4
end= 6
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
signal,samplerate = sf.read('sinais/ecolocalizacao.wav')
start = 0
end= 10
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
Trazendo também o exemplo do livro, o som da “Bowhead Whale”:
signal,samplerate = sf.read('sinais/bowhead-whale.mp3')
signal = signal[:,0]
s_8 = librosa.resample(signal,orig_sr=samplerate,target_sr=8000)
start = 0
end= 10
plot_spectrogram(s_8,8000,start=start,end=end,hop_length=512,n_fft=1024)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
c) Para o som de hélice, trazemos o som de um motor de avião, encontrado no pixabay:
signal,samplerate = sf.read('sinais/helice.mp3')
signal = signal[:,0]
start = 0
end= 5
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
e) Para o som de limpador de parabrisa, também trazemos um exemplo encontrado no pixabay:
signal,samplerate = sf.read('sinais/para-brisas.mp3')
s_8 = librosa.resample(signal,orig_sr=samplerate,target_sr=16000)
start = 0
end= 4
plot_spectrogram(s_8,16000,start=start,end=end,hop_length=512,n_fft=1024)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
f) Também do pixabay, porta batendo:
signal,samplerate = sf.read('sinais/door-slam.mp3')
signal = signal[:,0]
start = 0
end= 5
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
i) som de trompete, obtido em https://freesfx.co.uk/sfx/trumpet:
signal,samplerate = sf.read('sinais/trumpet2.mp3')
signal = signal[:,0]
start = 0
end= 3
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
j) som de coração (pixabay)
signal,samplerate = sf.read('sinais/heart_beat.mp3')
signal = signal[:,0]
s_8 = librosa.resample(signal,orig_sr=samplerate,target_sr=4000)
start = 0
end= 4
plot_spectrogram(s_8,4000,start=start,end=end,hop_length=128,n_fft=256)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)